<template>
  <div class="full-content">
    <!-- 表格 -->
    <a-table
      size="middle"
      :columns="columns"
      :data-source="list"
      bordered
      rowKey="id"
      :row-selection="choose ? rowSelection : null"
      :pagination="pagination"
      @change="
        (pagination, filters, sorter) => {
          this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter })
          this.loadData()
        }
      "
    >
      <template #title>
        <a-space>
          <a-input
            class="search-input-item"
            @pressEnter="loadData"
            v-model="listQuery['%name%']"
            placeholder="仓库名称"
          />
          <a-input
            class="search-input-item"
            @pressEnter="loadData"
            v-model="listQuery['%gitUrl%']"
            placeholder="仓库地址"
          />
          <a-select v-model="listQuery.repoType" allowClear placeholder="仓库类型" class="search-input-item">
            <a-select-option :value="'0'">GIT</a-select-option>
            <a-select-option :value="'1'">SVN</a-select-option>
          </a-select>

          <a-tooltip title="按住 Ctr 或者 Alt/Option 键点击按钮快速回到第一页">
            <a-button type="primary" :loading="loading" @click="loadData">搜索</a-button>
          </a-tooltip>
          <a-button type="primary" @click="handleAdd">新增</a-button>
          <a-button type="primary" @click="handleAddGitee">令牌导入</a-button>
        </a-space>
      </template>
      <a-tooltip #tooltip slot-scope="text" placement="topLeft" :title="text">
        <span>{{ text }}</span>
      </a-tooltip>

      <template #repoType slot-scope="text">
        <span v-if="text === 0">GIT</span>
        <span v-else-if="text === 1">SVN</span>
        <span v-else>未知</span>
      </template>
      <template #protocol slot-scope="text, record">
        <span v-if="text === 0">HTTP(S)</span>
        <span v-else-if="text === 1">SSH</span>
        <!-- if no protocol value, get a default value from gitUrl -->
        <span v-else>{{ record.gitUrl.indexOf('http') > -1 ? 'HTTP(S)' : 'SSH' }}</span>
      </template>
      <template #global slot-scope="text">
        <a-tag v-if="text === 'GLOBAL'">全局</a-tag>
        <a-tag v-else>工作空间</a-tag>
      </template>
      <template #operation slot-scope="text, record, index">
        <a-space>
          <a-button type="primary" size="small" @click="handleEdit(record)">编辑</a-button>
          <a-button type="danger" size="small" @click="handleDelete(record)">删除</a-button>
          <a-dropdown>
            <a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
              更多
              <down-outlined />
            </a>
            <template #overlay>
              <a-menu>
                <a-menu-item>
                  <a-button
                    size="small"
                    type="primary"
                    :disabled="(listQuery.page - 1) * listQuery.limit + (index + 1) <= 1"
                    @click="sortItemHander(record, index, 'top')"
                    >置顶</a-button
                  >
                </a-menu-item>
                <a-menu-item>
                  <a-button
                    size="small"
                    type="primary"
                    :disabled="(listQuery.page - 1) * listQuery.limit + (index + 1) <= 1"
                    @click="sortItemHander(record, index, 'up')"
                    >上移</a-button
                  >
                </a-menu-item>
                <a-menu-item>
                  <a-button
                    size="small"
                    type="primary"
                    :disabled="(listQuery.page - 1) * listQuery.limit + (index + 1) === listQuery.total"
                    @click="sortItemHander(record, index, 'down')"
                  >
                    下移
                  </a-button>
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </a-space>
      </template>
    </a-table>
    <!-- 编辑区 -->
    <a-modal
      :zIndex="1009"
      destroyOnClose
      v-model="editVisible"
      title="编辑仓库"
      @ok="handleEditOk"
      :maskClosable="false"
    >
      <a-form ref="editForm" :rules="rules" :model="temp" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
        <a-form-item label="仓库名称" prop="name">
          <a-input v-model="temp.name" :maxLength="50" placeholder="仓库名称" />
        </a-form-item>
        <a-form-item label="仓库地址" prop="gitUrl">
          <a-input-group compact>
            <a-select style="width: 20%" v-model="temp.repoType" name="repoType" placeholder="仓库类型">
              <a-select-option :value="0">GIT</a-select-option>
              <a-select-option :value="1">SVN</a-select-option>
            </a-select>
            <a-input style="width: 80%" :maxLength="250" v-model="temp.gitUrl" placeholder="仓库地址" />
          </a-input-group>
        </a-form-item>
        <a-form-item label="协议" prop="protocol">
          <a-radio-group v-model="temp.protocol" name="protocol">
            <a-radio :value="0">HTTP(S)</a-radio>
            <a-radio :value="1">SSH</a-radio>
          </a-radio-group>
        </a-form-item>
        <!-- HTTP(S) protocol use password -->
        <template v-if="temp.protocol === 0">
          <a-form-item prop="userName">
            <template #label>
              账号
              <a-tooltip v-if="!temp.id">
                <template #title> 账号支持引用工作空间变量：<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
                <question-circle-filled />
              </a-tooltip>
            </template>
            <a-input v-model="temp.userName" placeholder="登录用户">
              <a-icon #prefix type="user" />
              <a-tooltip
                v-if="temp.id"
                #suffix
                title=" 密码字段和密钥字段在编辑的时候不会返回，如果需要重置或者清空就请点我"
              >
                <a-button size="small" type="danger" @click="restHideField(temp)">清除</a-button>
              </a-tooltip>
            </a-input>
          </a-form-item>
          <a-form-item prop="password">
            <template #label>
              密码
              <a-tooltip v-if="!temp.id">
                <template #title> 密码支持引用工作空间变量：<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
                <question-circle-filled />
              </a-tooltip>
            </template>
            <a-input-password v-if="temp.id === undefined" v-model="temp.password" placeholder="登录密码">
              <a-icon #prefix type="lock" />
            </a-input-password>
            <a-input-password v-if="temp.id !== undefined" v-model="temp.password" placeholder="此处不填不会修改密码">
              <a-icon #prefix type="lock" />
            </a-input-password>
          </a-form-item>
        </template>
        <a-form-item v-if="temp.repoType === 1 && temp.protocol === 1" label="账号" prop="userName">
          <a-input v-model="temp.userName" placeholder="svn ssh 必填登录用户">
            <a-icon #prefix type="user" />
            <a-tooltip
              v-if="temp.id"
              #suffix
              title=" 密码字段和密钥字段在编辑的时候不会返回，如果需要重置或者清空就请点我"
            >
              <a-button size="small" type="danger" @click="restHideField(temp)">清除</a-button>
            </a-tooltip>
          </a-input>
        </a-form-item>
        <!-- SSH protocol use rsa private key -->
        <template v-if="temp.protocol === 1">
          <a-form-item prop="password">
            <template #label>
              密码
              <a-tooltip v-if="!temp.id">
                <template #title> 密码支持引用工作空间变量：<b>$ref.wEnv.xxxx</b> xxxx 为变量名称</template>
                <question-circle-filled />
              </a-tooltip>
            </template>
            <a-input-password v-model="temp.password" placeholder="证书密码">
              <a-icon #prefix type="lock" />
            </a-input-password>
          </a-form-item>
          <a-form-item label="私钥" prop="rsaPrv">
            <a-tooltip placement="topLeft">
              <template #title>
                <div>
                  <p style="color: #faa">
                    注意：目前对 SSH key 访问 git 仓库地址不支持使用 ssh-keygen -t rsa -C "邮箱" 方式生成的 SSH key
                    <br />需要使用 ssh-keygen -m PEM -t rsa -b 4096 -C "邮箱" 方式生成公私钥<br />
                  </p>
                  <p>如果在生成私钥的过程中有加密，那么需要把加密密码填充到上面的密码框中</p>
                  <p>支持两种方式填充：</p>
                  <p>
                    1. 完整的私钥内容 如: <br />-----BEGIN RSA PRIVATE KEY----- <br />
                    ..... <br />
                    -----END RSA PRIVATE KEY-----
                  </p>
                  <p>2. 私钥文件绝对路径（绝对路径前面添加 file: 前缀) 如: <br />file:/Users/Hotstrip/.ssh/id_rsa</p>
                </div>
              </template>
              <a-textarea
                :auto-size="{ minRows: 3, maxRows: 3 }"
                v-model="temp.rsaPrv"
                placeholder="私钥,不填将使用默认的 $HOME/.ssh 目录中的配置。支持配置文件目录:file:"
              ></a-textarea>
            </a-tooltip>
          </a-form-item>
          <!-- 公钥暂时没用到 -->
          <a-form-item label="公钥" prop="rsaPub" v-if="false">
            <a-textarea
              :auto-size="{ minRows: 3, maxRows: 3 }"
              v-model="temp.rsaPub"
              placeholder="公钥,不填将使用默认的 $HOME/.ssh 目录中的配置。支持配置文件目录:file:"
            ></a-textarea>
          </a-form-item>
        </template>
        <a-form-item label="共享" prop="global">
          <a-radio-group v-model="temp.global">
            <a-radio :value="true"> 全局</a-radio>
            <a-radio :value="false"> 当前工作空间</a-radio>
          </a-radio-group>
        </a-form-item>
        <!-- <a-form-item v-if="temp.id" prop="restHideField">
          <template #label>
            隐藏字段
            <a-tooltip>
              <template #title> 密码字段和私钥字段在编辑的时候不会返回，如果需要重置或者清空就请点我 </template>
              <question-circle-filled />
            </a-tooltip>
          </template>
          <a-button style="margin-left: 10px" type="danger" @click="restHideField(temp)">清除</a-button>
        </a-form-item> -->
        <a-form-item label="超时时间(s)" prop="timeout">
          <a-input-number v-model="temp.timeout" :min="0" placeholder="拉取仓库超时时间,单位秒" style="width: 100%" />
        </a-form-item>
      </a-form>
    </a-modal>
    <a-modal
      :zIndex="1009"
      destroyOnClose
      v-model="giteeImportVisible"
      title="通过私人令牌导入仓库"
      width="80%"
      :footer="null"
      :maskClosable="false"
    >
      <a-form
        :label-col="{ span: 4 }"
        :rules="giteeImportFormRules"
        :model="giteeImportForm"
        ref="giteeImportForm"
        :wrapper-col="{ span: 20 }"
      >
        <a-form-item
          prop="token"
          label="私人令牌"
          help="使用私人令牌，可以在你不输入账号密码的情况下对你账号内的仓库进行管理，你可以在创建令牌时指定令牌所拥有的权限。"
        >
          <a-tooltip :title="`${giteeImportForm.type} 的令牌${importTypePlaceholder[giteeImportForm.type]}`">
            <!-- <a-input v-model="giteeImportForm.token" :placeholder="importTypePlaceholder[giteeImportForm.type]">
              <a-select #addonBefore style="width: 100px" @change="importChange" v-model="giteeImportForm.type">
                <a-select-option :value="item" v-for="item in Object.keys(providerData)" :key="item"> {{ item }}</a-select-option>
              </a-select>

              <a-button #addonAfter size="small" type="primary" icon="search" @click="handleGiteeImportFormOk"></a-button>
            </a-input> -->
            <a-input-group compact>
              <a-select style="width: 10%" @change="importChange" v-model="giteeImportForm.type">
                <a-select-option :value="item" v-for="item in Object.keys(providerData)" :key="item">
                  {{ item }}</a-select-option
                >
              </a-select>

              <a-input-search
                style="width: 90%; margin-top: 1px"
                enter-button
                v-model="giteeImportForm.token"
                @search="handleGiteeImportFormOk"
                :placeholder="importTypePlaceholder[giteeImportForm.type]"
              />
            </a-input-group>
          </a-tooltip>
        </a-form-item>
        <a-form-item prop="address" label="地址">
          <a-input v-model="giteeImportForm.address" placeholder="请填写平台地址" />
        </a-form-item>
        <a-form-item
          prop="condition"
          label="搜索"
          help="输入仓库名称或者仓库路径进行搜索"
          v-if="providerData[giteeImportForm.type].query"
        >
          <a-input v-model="giteeImportForm.condition" placeholder="输入仓库名称或者仓库路径进行搜索" />
        </a-form-item>
      </a-form>
      <a-table
        :loading="loading"
        size="middle"
        :columns="reposColumns"
        :data-source="repos"
        bordered
        rowKey="full_name"
        @change="reposChange"
        :pagination="reposPagination"
      >
        <template #private slot-scope="text, record">
          <a-switch size="small" :disabled="true" :checked="record.private" />
        </template>
        <a-tooltip #name slot-scope="text" placement="topLeft" :title="text">
          <span>{{ text }}</span>
        </a-tooltip>
        <a-tooltip #full_name slot-scope="text" placement="topLeft" :title="text">
          <span>{{ text }}</span>
        </a-tooltip>
        <a-tooltip #url slot-scope="text" placement="topLeft" :title="text">
          <span>{{ text }}</span>
        </a-tooltip>
        <a-tooltip #description slot-scope="text" placement="topLeft" :title="text">
          <span>{{ text }}</span>
        </a-tooltip>

        <template #operation slot-scope="text, record">
          <a-button type="primary" size="small" :disabled="record.exists" @click="handleGiteeRepoAdd(record)">{{
            record.exists ? '已存在' : '添加'
          }}</a-button>
        </template>
      </a-table>
    </a-modal>
    <div style="padding-top: 50px" v-if="choose">
      <div
        :style="{
          position: 'absolute',
          right: 0,
          bottom: 0,
          width: '100%',
          borderTop: '1px solid #e9e9e9',
          padding: '10px 16px',
          background: '#fff',
          textAlign: 'right',
          zIndex: 1
        }"
      >
        <a-space>
          <a-button
            @click="
              () => {
                this.$emit('cancel')
              }
            "
          >
            取消
          </a-button>
          <a-button type="primary" @click="handerConfirm"> 确定 </a-button>
        </a-space>
      </div>
    </div>
  </div>
</template>
<script>
import {
  providerInfo,
  authorizeRepos,
  deleteRepository,
  editRepository,
  getRepositoryList,
  restHideField,
  sortItem
} from '@/api/repository'
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, parseTime } from '@/utils/const'

export default {
  components: {},
  props: {
    choose: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      loading: false,
      PAGE_DEFAULT_SIZW_OPTIONS: ['15', '20', '25', '30', '35', '40', '50'],
      listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY, { limit: 15 }),
      list: [],
      providerData: {
        gitee: {
          baseUrl: 'https://gitee.com',
          name: 'gitee',
          query: true
        }
      },
      total: 0,
      temp: {},
      isSystem: false,
      editVisible: false,
      giteeImportVisible: false,
      repos: [],
      username: null,

      columns: [
        {
          title: '仓库名称',
          dataIndex: 'name',
          width: 200,
          sorter: true,
          ellipsis: true,
          scopedSlots: { customRender: 'tooltip' }
        },
        {
          title: '仓库地址',
          dataIndex: 'gitUrl',
          width: 300,
          sorter: true,
          ellipsis: true,
          scopedSlots: { customRender: 'tooltip' }
        },
        {
          title: '仓库类型',
          dataIndex: 'repoType',
          width: 100,
          sorter: true,
          ellipsis: true,
          scopedSlots: { customRender: 'repoType' }
        },
        {
          title: '协议',
          dataIndex: 'protocol',
          width: 100,
          sorter: true,
          ellipsis: true,
          scopedSlots: { customRender: 'protocol' }
        },
        {
          title: '共享',
          dataIndex: 'workspaceId',
          ellipsis: true,
          scopedSlots: { customRender: 'global' },
          width: '90px'
        },
        {
          title: '创建人',
          dataIndex: 'createUser',
          ellipsis: true,
          scopedSlots: { customRender: 'tooltip' },
          width: '120px'
        },
        {
          title: '修改人',
          dataIndex: 'modifyUser',
          ellipsis: true,
          scopedSlots: { customRender: 'tooltip' },
          width: '120px'
        },
        {
          title: '创建时间',
          dataIndex: 'createTimeMillis',
          sorter: true,
          customRender: (text) => parseTime(text),
          width: '170px'
        },
        {
          title: '修改时间',
          dataIndex: 'modifyTimeMillis',
          sorter: true,
          customRender: (text) => parseTime(text),
          width: '170px'
        },
        {
          title: '操作',
          dataIndex: 'operation',
          fixed: 'right',
          align: 'center',
          width: '180px',
          scopedSlots: { customRender: 'operation' }
        }
      ],
      reposColumns: [
        { title: '仓库名称', dataIndex: 'name', ellipsis: true, scopedSlots: { customRender: 'name' } },
        { title: '仓库路径', dataIndex: 'full_name', ellipsis: true, scopedSlots: { customRender: 'full_name' } },
        { title: 'GitUrl', dataIndex: 'url', ellipsis: true, scopedSlots: { customRender: 'url' } },

        {
          title: '描述',
          dataIndex: 'description',

          ellipsis: true,
          scopedSlots: { customRender: 'description' }
        },
        { title: '私有', dataIndex: 'private', width: 80, ellipsis: true, scopedSlots: { customRender: 'private' } },
        {
          title: '操作',
          dataIndex: 'operation',
          width: 100,
          scopedSlots: { customRender: 'operation' },
          align: 'left'
        }
      ],
      giteeImportForm: Object.assign({}, PAGE_DEFAULT_LIST_QUERY, {
        limit: 15,
        type: 'gitee',
        address: 'https://gitee.com'
      }),
      giteeImportFormRules: {
        token: [{ required: true, message: '请输入私人令牌', trigger: 'blur' }]
        // address: [{ required: true, message: "请填写平台地址", trigger: "blur" }],
      },
      rules: {
        name: [{ required: true, message: '请填写仓库名称', trigger: 'blur' }],
        gitUrl: [{ required: true, message: '请填写仓库地址', trigger: 'blur' }]
      },
      importTypePlaceholder: {
        gitee: '在 设置-->安全设置-->私人令牌 中获取',
        github: '在 Settings-->Developer settings-->Personal access tokens 中获取',
        gitlab_v3: '在 preferences-->Access Tokens 中获取',
        gitlab: '在 preferences-->Access Tokens 中获取',
        gitea: '在 设置 --> 应用 --> 生成令牌',
        gogs: '在 设置 --> 应用 --> 生成令牌',
        other: '请输入私人令牌'
      },
      tableSelections: []
    }
  },
  computed: {
    // 分页
    pagination() {
      return COMPUTED_PAGINATION(this.listQuery, this.PAGE_DEFAULT_SIZW_OPTIONS)
    },
    reposPagination() {
      return COMPUTED_PAGINATION(this.giteeImportForm, this.PAGE_DEFAULT_SIZW_OPTIONS)
    },
    rowSelection() {
      return {
        onChange: (selectedRowKeys) => {
          this.tableSelections = selectedRowKeys
        },
        selectedRowKeys: this.tableSelections,
        type: 'radio'
      }
    }
  },
  watch: {},
  created() {
    this.loadData()
  },
  methods: {
    CHANGE_PAGE,
    // 加载数据
    async loadData(pointerEvent) {
      this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page
      this.loading = true
      getRepositoryList(this.listQuery).then((res) => {
        if (res.code === 200) {
          this.list = res.data.result
          this.listQuery.total = res.data.total
        }
        this.loading = false
      })
      const response = await providerInfo()
      if (response.code === 200) {
        this.providerData = response.data
      }
    },
    importChange(value) {
      this.giteeImportForm.address = this.providerData[value].baseUrl
    },
    // // 筛选
    // handleFilter() {
    //   this.loadData();
    // },
    // 添加
    handleAdd() {
      this.temp = {
        repoType: 0,
        protocol: 0
      }
      this.editVisible = true
    },
    handleAddGitee() {
      this.giteeImportVisible = true
    },
    handleGiteeImportFormOk() {
      this.$refs['giteeImportForm'].validate((valid) => {
        if (!valid) {
          return false
        }
        authorizeRepos(this.giteeImportForm).then((res) => {
          if (res.code === 200) {
            // 成功
            //this.username = res.data.username;
            this.giteeImportForm.total = res.data.total
            this.repos = res.data.result
          }
        })
      })
    },
    reposChange(pagination) {
      this.giteeImportForm.page = pagination.current
      this.giteeImportForm.limit = pagination.pageSize
      this.handleGiteeImportFormOk()
    },
    handleGiteeRepoAdd(record) {
      editRepository({
        repoType: 0,
        protocol: 0,
        userName: record.username,
        password: this.giteeImportForm.token,
        name: record.name,
        gitUrl: record.url
      }).then((res) => {
        if (res.code === 200) {
          // 成功
          $notification.success({
            message: res.msg
          })
          record.exists = true
          this.loadData()
        }
      })
    },
    // 修改
    handleEdit(record) {
      this.temp = Object.assign({}, record)
      if (this.temp.protocol === undefined) {
        this.temp.protocol = this.temp.gitUrl.indexOf('http') > -1 ? 0 : 1
      }
      this.temp = { ...this.temp, global: record.workspaceId === 'GLOBAL', workspaceId: '' }
      this.editVisible = true
    },
    // 提交节点数据
    handleEditOk() {
      // 检验表单
      this.$refs['editForm'].validate((valid) => {
        if (!valid) {
          return false
        }
        // 提交数据
        editRepository(this.temp).then((res) => {
          if (res.code === 200) {
            // 成功
            $notification.success({
              message: res.msg
            })
            this.editVisible = false
            this.loadData()
            this.$refs['editForm'].resetFields()
          }
        })
      })
    },
    // 删除
    handleDelete(record) {
      $confirm({
        title: '系统提示',
        content: '真的要删除仓库信息么？',
        okText: '确认',
        cancelText: '取消',
        onOk: () => {
          const params = {
            id: record.id
            //isRealDel: this.isSystem,
          }
          // 删除
          deleteRepository(params).then((res) => {
            if (res.code === 200) {
              $notification.success({
                message: res.msg
              })
              this.loadData()
            }
          })
        }
      })
    },

    // 清除隐藏字段
    restHideField(record) {
      $confirm({
        title: '系统提示',
        content: '真的要清除仓库隐藏字段信息么？（密码，私钥）',
        okText: '确认',
        cancelText: '取消',
        onOk: () => {
          // 恢复
          restHideField(record.id).then((res) => {
            if (res.code === 200) {
              $notification.success({
                message: res.msg
              })
              this.loadData()
            }
          })
        }
      })
    },

    // 排序
    sortItemHander(record, index, method) {
      const msgData = {
        top: '确定要将此数据置顶吗？',
        up: '确定要将此数上移吗？',
        down: '确定要将此数据下移吗？下移操作可能因为列表后续数据没有排序值操作无效！'
      }
      let msg = msgData[method] || '确定要操作吗？'
      if (!record.sortValue) {
        msg += ' 当前数据为默认状态,操后上移或者下移可能不会达到预期排序,还需要对相关数据都操作后才能达到预期排序'
      }
      // console.log(this.list, index, this.list[method === "top" ? index : method === "up" ? index - 1 : index + 1]);
      const compareId = this.list[method === 'top' ? index : method === 'up' ? index - 1 : index + 1].id
      $confirm({
        title: '系统提示',
        content: msg,
        okText: '确认',
        cancelText: '取消',
        onOk: () => {
          // 解锁
          sortItem({
            id: record.id,
            method: method,
            compareId: compareId
          }).then((res) => {
            if (res.code == 200) {
              $notification.success({
                message: res.msg
              })

              this.loadData()
              return false
            }
          })
        }
      })
    },
    // 确认
    handerConfirm() {
      if (!this.tableSelections.length) {
        $notification.warning({
          message: '请选择要使用的仓库'
        })
        return
      }
      const selectData = this.list.filter((item) => {
        return item.id === this.tableSelections[0]
      })[0]

      this.$emit('confirm', `${selectData.id}`)
    }
  }
}
</script>
<style scoped>
/* .filter {
  margin-bottom: 10px;
}

.btn-add {
  margin-left: 10px;
  margin-right: 0;
} */
</style>
